package org.zxyj.core.web.resolver;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;
import org.zxyj.core.entity.Result;
import org.zxyj.core.exception.ServiceException;
import org.zxyj.core.exception.UnifyException;

/**
 * @author zhaoyong
 * @version 2016年2月22日
 */
public class CustomSimpleMappingExceptionResolver extends SimpleMappingExceptionResolver {

	private static Logger logger = LoggerFactory.getLogger(CustomSimpleMappingExceptionResolver.class);

	private static final Integer DEFAULT_RESULT_CODE = 500;

	private Integer defaultResultCode = DEFAULT_RESULT_CODE;

	@Override
	protected ModelAndView doResolveException(HttpServletRequest request, HttpServletResponse response, Object handler,
			Exception ex) {
		logger.error("Resolving exception from handler [{}]: cause: {}", handler, ex);

		String viewName = determineViewName(ex, request);
		if (!StringUtils.isEmpty(viewName)) {
			// 判断是否是异步请求
			if (!(request.getHeader("accept").indexOf("application/json") > -1
					|| (request.getHeader("X-Requested-With") != null
							&& request.getHeader("X-Requested-With").indexOf("XMLHttpRequest") > -1))) {
				Integer statusCode = determineStatusCode(request, viewName);
				if (statusCode != null) {
					applyStatusCodeIfPossible(request, response, statusCode);
				}
				return getModelAndView(viewName, ex, request);
			} else {
				try {
					Result<?> result = new Result<String>();
					if (ex instanceof ServiceException) {
						ServiceException se = (ServiceException) ex;
						result.setResultCode(se.getErrorNo());
					} else if (ex instanceof UnifyException) {
						UnifyException se = (UnifyException) ex;
						result.setResultCode(se.getErrorNo());
					} else {
						result.setResultCode("" + defaultResultCode);
					}
					PrintWriter out = response.getWriter();
					out.write("");
					out.flush();
				} catch (IOException e) {
					logger.error("");
				}
				return null;
			}
		} else {
			logger.warn("Resolving exception from handler [{}] with no view", handler);
			return null;
		}
	}

	public void setDefaultResultCode(Integer defaultResultCode) {
		this.defaultResultCode = defaultResultCode;
	}

}